package com.cy.cy2025.view

import android.content.Context
import android.graphics.Point
import android.graphics.Rect
import android.hardware.Camera
import android.hardware.Camera.PictureCallback
import android.hardware.Camera.ShutterCallback
import android.media.CamcorderProfile
import android.media.MediaRecorder
import android.os.Build
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import java.io.File
import java.io.FileOutputStream
import java.io.IOException

/**
 * Created by cy on 2018/4/23.
 */
class CameraView : SurfaceView {
    var cameraId: Int = Camera.CameraInfo.CAMERA_FACING_BACK

    var mCamera: Camera? = null
    var surfaceHolder: SurfaceHolder? = null


    constructor(context: Context?) : this(context, null)

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
        init()
    }

    fun init() {
        surfaceHolder = getHolder()
        surfaceHolder!!.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(holder: SurfaceHolder) {
                try {
                    startPreview()
                }catch (e: Exception) {
                    e.printStackTrace()
                }
            }

            override fun surfaceChanged(
                holder: SurfaceHolder,
                format: Int,
                width: Int,
                height: Int
            ) {
            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                try {
                    mCamera!!.setPreviewDisplay(null)
                    mCamera!!.stopPreview()
                } catch (e: Exception) {
                }
            }
        })


        //设置触摸对焦
        setOnTouchListener(object : OnTouchListener {
            override fun onTouch(view: View?, motionEvent: MotionEvent): Boolean {
                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                    onFocus(Point((motionEvent.getX()).toInt(), (motionEvent.getY()).toInt()))
                }
                return false
            }
        })
    }

    fun startPreview(){
        mCamera = Camera.open(cameraId)
        try {
            mCamera!!.setPreviewDisplay(surfaceHolder)
        } catch (e: IOException) {
            e.printStackTrace()
        }
        mCamera!!.setDisplayOrientation(90)
        val parameters = mCamera!!.getParameters()
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            parameters.setRotation(90)
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO)
        } else {
            //parameters.set("preview-flip", "flip-h");
            parameters.setRotation(270)
        }

        mCamera!!.setParameters(parameters)
        mCamera!!.startPreview()
    }


    fun switchCamera() {
        if (Camera.getNumberOfCameras() < 2) {
            return
        }

        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            //后置摄像头
            cameraId = Camera.CameraInfo.CAMERA_FACING_FRONT
        } else {  // 前置摄像头
            cameraId = Camera.CameraInfo.CAMERA_FACING_BACK
        }

        mCamera!!.stopPreview() //停掉原来摄像头的预览
        mCamera!!.release() //释放资源
        mCamera = null //取消原来摄像头
        mCamera = Camera.open(cameraId) //打开当前选中的摄像头
        try {
            val parameters = mCamera!!.getParameters()
            val SupportedPreviewSizes = parameters.getSupportedPreviewSizes() // 获取支持预览照片的尺寸
            val previewSize = SupportedPreviewSizes.get(0) // 从List取出Size
            parameters.setPreviewSize(previewSize.width, previewSize.height) //
            //设置预览照片的大小
            val supportedPictureSizes = parameters.getSupportedPictureSizes() // 获取支持保存图片的尺寸
            val pictureSize = supportedPictureSizes.get(0) // 从List取出Size
            parameters.setPictureSize(pictureSize.width, pictureSize.height) //
            //设置照片的大小
            mCamera!!.setParameters(parameters)

            mCamera!!.setPreviewDisplay(surfaceHolder)
        } catch (e: IOException) {
            e.printStackTrace()
        }
        val parameters = mCamera!!.getParameters()
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            mCamera!!.setDisplayOrientation(90)
            parameters.setRotation(90)
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO)
            setRotationY(0f)
        } else {
            //setRotationY(180);
            mCamera!!.setDisplayOrientation(90)

            //parameters.set("preview-flip", "flip-v");
            parameters.setRotation(270)
        }

        mCamera!!.setParameters(parameters)
        mCamera!!.startPreview()
    }


    /**
     * 手动聚焦
     *
     * @param point 触屏坐标
     */
    protected fun onFocus(point: Point): Boolean {
        if (mCamera == null) {
            return false
        }

        var parameters: Camera.Parameters? = null
        try {
            parameters = mCamera!!.getParameters()
        } catch (e: Exception) {
            e.printStackTrace()
            return false
        }

        //不支持设置自定义聚焦，则使用自动聚焦，返回
        if (Build.VERSION.SDK_INT >= 14) {
            if (parameters.getMaxNumFocusAreas() <= 0) {
                return focus()
            }

            Log.i("CameraView", "onCameraFocus:" + point.x + "," + point.y)

            //定点对焦
            val areas: MutableList<Camera.Area?> = ArrayList<Camera.Area?>()
            var left = point.x - 300
            var top = point.y - 300
            var right = point.x + 300
            var bottom = point.y + 300
            left = if (left < -1000) -1000 else left
            top = if (top < -1000) -1000 else top
            right = if (right > 1000) 1000 else right
            bottom = if (bottom > 1000) 1000 else bottom
            areas.add(Camera.Area(Rect(left, top, right, bottom), 100))
            parameters.setFocusAreas(areas)
            try {
                val SupportedPreviewSizes = parameters.getSupportedPreviewSizes() // 获取支持预览照片的尺寸
                val previewSize: Camera.Size? = SupportedPreviewSizes.get(0) // 从List取出Size
                //parameters.setPreviewSize(previewSize.width, previewSize.height);//
                //设置预览照片的大小
                val supportedPictureSizes = parameters.getSupportedPictureSizes() // 获取支持保存图片的尺寸
                val pictureSize = supportedPictureSizes.get(0) // 从List取出Size
                parameters.setPictureSize(pictureSize.width, pictureSize.height) //
                //设置照片的大小
                mCamera!!.setParameters(parameters)
            } catch (e: Exception) {
                e.printStackTrace()
                return false
            }
        }


        return focus()
    }

    private fun focus(): Boolean {
        try {
            mCamera!!.autoFocus(null)
        } catch (e: Exception) {
            e.printStackTrace()
            return false
        }
        return true
    }


    var han: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            mCamera!!.startPreview()
        }
    }

    fun save(filePath: String, data: ByteArray?, callBack: () -> Unit) {
        Thread(object : Runnable {
            override fun run() {
                val f = File(filePath)
                if (f.exists()) {
                    f.delete()
                }
                try {
                    f.createNewFile()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                try {
                    val os = FileOutputStream(f)
                    os.write(data)
                    os.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                han.sendEmptyMessage(0)
                han.post {
                    callBack.invoke()
                }
            }
        }).start()
    }


    /**
     * 拍照
     *
     * @param jpgFilePath 照片保持路径
     * @param sound       是否需要系统快门声
     */
    fun takePicture(jpgFilePath: String, sound: Boolean, callBack: () -> Unit ) {
        mCamera!!.takePicture(
            if (sound) object : ShutterCallback {
                override fun onShutter() {
                }
            } else null,
            null,  //这里是原图回调，但是返回的数据老是空的，没什么卵用，所以干脆不用它
            object : PictureCallback {
                override fun onPictureTaken(bytes: ByteArray?, camera: Camera?) { //jepg回调
                    if (!TextUtils.isEmpty(jpgFilePath) && bytes != null && bytes.size > 0) {
                        save(jpgFilePath, bytes,callBack)
                    }
                }
            }
        )
    }


    var mMediaRecorder: MediaRecorder = MediaRecorder() //录制视频器
    var isRecording: Boolean = false //是否正在录制视频
    var isOnPause: Boolean = false
    var recordTime: Long = 0 //录制时长(毫秒数)
    var startRecordTime: Long = 0 //开始录制的时间

    /**
     * 开始录制mp4
     */
    fun startRecorderMp4(mp4FilePath: String) {
        val f = File(mp4FilePath)
        if (f.exists()) {
            f.delete()
        }
        if (mCamera != null) {
            stopRecorderMp4()
        }
        mCamera!!.unlock()
        setConfigRecord()
        mMediaRecorder.setOutputFile(mp4FilePath)
        try {
            //开始录制
            mMediaRecorder.prepare()
            mMediaRecorder.start()
            startRecordTime = System.currentTimeMillis()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        isRecording = true
    }

    /**
     * 暂停录制mp4
     */
    fun pauseRecorderMp4(mp4FilePath: String?) {
    }

    /**
     * 恢复录制mp4
     */
    fun resumeRecorderMp4(mp4FilePath: String?) {
    }

    /**
     * 停止录制mp4
     *
     * @return 录制时长(秒数)
     */
    fun stopRecorderMp4(): Int {
        try {
            mMediaRecorder.stop()
            val time =
                (recordTime / 1000 + (System.currentTimeMillis() - startRecordTime) / 1000).toInt()
            recordTime = 0
            return time
        } catch (e: Exception) {
            e.printStackTrace()
            return 0
        }
    }


    /**
     * 配置MediaRecorder()
     */
    private fun setConfigRecord() {
        mMediaRecorder = MediaRecorder()
        mMediaRecorder.reset()
        mMediaRecorder.setCamera(mCamera)
        mMediaRecorder.setOnErrorListener(object : MediaRecorder.OnErrorListener {
            override fun onError(mediaRecorder: MediaRecorder?, i: Int, i1: Int) {
            }
        })

        //使用SurfaceView预览
        mMediaRecorder.setPreviewDisplay(surfaceHolder!!.getSurface())

        //1.设置采集声音
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC)
        //设置采集图像
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA)
        //2.设置视频，音频的输出格式 mp4
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT)
        //3.设置音频的编码格式
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        //设置图像的编码格式
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
        //设置立体声
//        mediaRecorder.setAudioChannels(2);
        //设置最大录像时间 单位：毫秒
//        mediaRecorder.setMaxDuration(60 * 1000);
        //设置最大录制的大小 单位，字节
//        mediaRecorder.setMaxFileSize(1024 * 1024);
        //音频一秒钟包含多少数据位
        val mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P)
        mMediaRecorder.setAudioEncodingBitRate(44100)
        if (mProfile.videoBitRate > 2 * 1024 * 1024) mMediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024)
        else mMediaRecorder.setVideoEncodingBitRate(1024 * 1024)
        mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate)

        //设置选择角度，顺时针方向，因为默认是逆向90度的，这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            mMediaRecorder.setOrientationHint(90)
        } else {
            mMediaRecorder.setOrientationHint(270)
        }

        //设置录像的分辨率
        //mMediaRecorder.setVideoSize(352, 288);
        mMediaRecorder.setVideoSize(640, 480)
    }
}